﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using FRW.Common;

namespace FRW.Common.Configuration
{
    public class Configuration<T> where T : IConfiguration, new()
    {
        // TODO these are only her incase we support option of binary later, it could be written without them
        private delegate object SerialiseInputDelegate(Type objToSerialise, string fileName);
        private delegate void SerialiseOutputDelegate(object objToSerialise, string fileName);

        #region Fields

        private static T _item;
        private string _fileName = typeof(T).ToString() + ".xml";
        private SerialiseInputDelegate _serialInput;
        private SerialiseOutputDelegate _serialOutput;

        #endregion

        #region Properties

        public T Item
        {
            get { return _item; }
            set { _item = value; }
        }

        public string FileName
        {
            get { return _fileName; }
            set { _fileName = value; }
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        public Configuration(string fileName = null)
        {
            if (fileName != null)
            {
                _fileName = fileName;
            }

            //TODO should we refactor this to be the class type
            _serialInput = Serialize.FromXMLFile;
            _serialOutput = Serialize.ToXMLFile;

            _item = new T();
        }

        public void SetFile(string fileName)
        {
            _fileName = fileName;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public bool Load(string fileName = null)
        {
            if (fileName == null)
            {
                fileName = PathManager.Instance.ApplicationFolder + @"\" + _fileName;
            }

            bool configurationLoaded = false;

            if (File.Exists(fileName))
            {
                try
                {
                    _item = (T)_serialInput(typeof(T), fileName);
                    configurationLoaded = true;

                    if (_item == null)
                    {
                        _item = new T();
                        _item.DefaultConfiguration();
                    }
                    else
                    {
                        _item.CheckConfiguration();
                    }
                }
                catch
                {
                    _item = new T();
                    _item.DefaultConfiguration();
                }
            }

            return configurationLoaded;
        }

        public void LoadDefault()
        {
            if (_item == null)
            {
                _item = new T();
            }
            _item.DefaultConfiguration();
        }

        public void Save(string fileName = null)
        {
            if (fileName == null)
            {
                fileName = PathManager.Instance.ApplicationFolder + @"\" + _fileName;
            }

            _serialOutput(_item, fileName);
        }
    }
}
